home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
xlib
/
xlib06
/
xline.asm
< prev
next >
Wrap
Assembly Source File
|
1993-09-12
|
5KB
|
317 lines
;-----------------------------------------------------------------------
; MODULE XLINE
;
; Line drawing functions.
;
; Compile with Tasm.
; C callable.
;
;
; ****** XLIB - Mode X graphics library ****************
; ****** ****************
; ****** Written By Themie Gouthas ****************
;
; egg@dstos3.dsto.gov.au
; teg@bart.dsto.gov.au
;-----------------------------------------------------------------------
include xlib.inc
include xline.inc
.code
ModeXAddr macro
mov cl,bl
push dx
mov dx,[_ScrnLogicalByteWidth]
mul dx
pop dx
shr bx,2
add bx,ax
add bx,[PgOffs]
and cl,3
endm
;-----------------------------------------------------------------------
; _x_line
;
; Line drawing function for all MODE X 256 Color resolutions
; Based on code from "PC and PS/2 Video Systems" by Richard Wilton.
;
; Compile with Tasm.
; C callable.
;
_x_line proc
ARG x1:word,y1:word,x2:word,y2:word,Color:word,PgOffs:word
LOCAL vertincr:word,incr1:word,incr2:word,routine:word=LocalStk
push bp ; Set up stack frame
mov bp,sp
sub sp,LocalStk
push si
push di
mov ax,0a000h
mov es,ax
mov dx,SC_INDEX ; setup for plane mask access
; check for vertical line
mov si,[_ScrnLogicalByteWidth]
mov cx,[x2]
sub cx,[x1]
jz VertLine
; force x1 < x2
jns L01
neg cx
mov bx,[x2]
xchg bx,[x1]
mov [x2],bx
mov bx,[y2]
xchg bx,[y1]
mov [y2],bx
; calc dy = abs(y2 - y1)
L01:
mov bx,[y2]
sub bx,[y1]
jnz short skip
jmp HorizLine
skip: jns L03
neg bx
neg si
; select appropriate routine for slope of line
L03:
mov [vertincr],si
mov [routine],offset LoSlopeLine
cmp bx,cx
jle L04
mov [routine],offset HiSlopeLine
xchg bx,cx
; calc initial decision variable and increments
L04:
shl bx,1
mov [incr1],bx
sub bx,cx
mov si,bx
sub bx,cx
mov [incr2],bx
; calc first pixel address
push cx
mov ax,[y1]
mov bx,[x1]
ModeXAddr
mov di,bx
mov al,1
shl al,cl
mov ah,al ; duplicate nybble
shl al,4
add ah,al
mov bl,ah
pop cx
inc cx
jmp [routine]
; routine for verticle lines
VertLine:
mov ax,[y1]
mov bx,[y2]
mov cx,bx
sub cx,ax
jge L31
neg cx
mov ax,bx
L31:
inc cx
mov bx,[x1]
push cx
ModeXAddr
mov ah,1
shl ah,cl
mov al,MAP_MASK
out dx,ax
pop cx
mov ax, word ptr [Color]
; draw the line
L32:
mov es:[bx],al
add bx,si
loop L32
jmp Lexit
; routine for horizontal line
HorizLine:
push ds
mov ax,[y1]
mov bx,[x1]
ModeXAddr
mov di,bx ; set dl = first byte mask
mov dl,00fh
shl dl,cl
mov cx,[x2] ; set dh = last byte mask
and cl,3
mov dh,00eh
shl dh,cl
not dh
; determine byte offset of first and last pixel in line
mov ax,[x2]
mov bx,[x1]
shr ax,2 ; set ax = last byte column
shr bx,2 ; set bx = first byte column
mov cx,ax ; cx = ax - bx
sub cx,bx
mov ax,dx ; mov end byte masks to ax
mov dx,SC_INDEX ; setup dx for VGA outs
mov bx, [Color]
; set pixels in leftmost byte of line
or cx,cx ; is start and end pt in same byte
jnz L42 ; no !
and ah,al ; combine start and end masks
jmp short L44
L42: push ax
mov ah,al
mov al,MAP_MASK
out dx,ax
mov al,bl
stosb
dec cx
; draw remainder of the line
L43:
mov ah,0Fh
mov al,MAP_MASK
out dx,ax
mov al,bl
rep stosb
pop ax
; set pixels in rightmost byte of line
L44:
mov al,MAP_MASK
out dx, ax
mov byte ptr es:[di],bl
pop ds
jmp short Lexit
; routine for dy >= dx (slope <= 1)
LoSlopeLine:
mov al,MAP_MASK
mov bh,byte ptr [Color]
L10:
mov ah,bl
L11:
or ah,bl
rol bl,1
jc L14
; bit mask not shifted out
or si,si
jns L12
add si,[incr1]
loop L11
out dx,ax
mov es:[di],bh
jmp short Lexit
L12:
add si,[incr2]
out dx,ax
mov es:[di],bh
add di,[vertincr]
loop L10
jmp short Lexit
; bit mask shifted out
L14: out dx,ax
mov es:[di],bh
inc di
or si,si
jns L15
add si,[incr1]
loop L10
jmp short Lexit
L15:
add si,[incr2]
add di,[vertincr]
loop L10
jmp short Lexit
; routine for dy > dx (slope > 1)
HiSlopeLine:
mov bx,[vertincr]
mov al,MAP_MASK
L21: out dx,ax
push ax
mov ax,[Color]
mov es:[di],al
pop ax
add di,bx
L22:
or si,si
jns L23
add si,[incr1]
loop L21
jmp short Lexit
L23:
add si,[incr2]
rol ah,1
adc di,0
lx21: loop L21
; return to caller
Lexit:
pop di
pop si
mov sp,bp
pop bp
ret
_x_line endp
end